﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Data.SqlServerCe;
using System.Data;
using System.Collections.ObjectModel;
using OverStore.Configuration.Builder.Fluent;
using OverStore.Configuration;
using OverStore.Configuration.Components;
using OverStore.Configuration.Builder;
using System.Reflection;
using OverStore.Runtime.Storage;
using OverStore.Configuration.ObjectRepository.Depot;

namespace OverStore.TutorialAsTest.UnitTest.Configuration.Rdbms.AttachedKeys
{
    [TestClass]
    public class AttachedKey_Test
    {
        protected OverStoreConfiguration CreateConfig(string connectionString)
        {
            return OverStoreFluent.Configure()
                .LogToConsole()
                .ConnectToDatabase<SqlCeConnection>(connectionString, ProcessOpenedReadersMode.ForciblyCloseReaders)
                .CustomClassRepository<NumberName, int>()
                    .WithDepot(new DelegateDepotConfiguration<NumberName, int>
                                {                                    
                                    IdentifierGenerator = Component.IdentifierGenerator.Delegate<NumberName, int>(
                                        (item, current) => current + 5, 5000)
                                })
                    .WithMapper(Component.Mapper.Delegate<NumberName>((item, name, p) =>
                            {
                                if (name == "orig__Id")
                                    return p.GetIdentifier<NumberName, int>(item);
                                if (name == "Name")
                                    return item.Name;
                                return Missing.Value;
                            },
                            (data, item, provider) =>
                            {
                                item.Name = data.GetString("Name");
                            }))
                    .CommandsFromTable(false, Component.CreateTable("Names").Key<int>("Id").Column<string>("Name"))
                    .NoChangesTracking().NoErrorTransforming().NoAttachingSupport()
                .EndObjectRepository()
			.End();
        }


        [TestMethod]
        public void AttachedKeys_AccessExistingData()
        {
            var connectionString = TestHelper.CreateTestDbCopyAndBuildConnectionString();
            var config = CreateConfig(connectionString);
            using (var session = config.CreateSession())
            {
                var thousand = session.GetByIdentifier<NumberName, int>(1000);
                Assert.IsNotNull(thousand);
                Assert.AreEqual("One thousand", thousand.Name);

                var item2 = session.GetByIdentifier<NumberName, int>(1000);
                Assert.AreSame(thousand, item2);

                var two = session.GetByIdentifier<NumberName, int>(2);
                Assert.IsNotNull(two);
                Assert.AreEqual("Two", two.Name);
            }
        }

        [TestMethod]
        public void AttachedKeys_AddItems()
        {
            var connectionString = TestHelper.CreateTestDbCopyAndBuildConnectionString();
            var config = CreateConfig(connectionString);
            using (var session = config.CreateSession())
            {
                var thousand = session.GetByIdentifier<NumberName, int>(1000);
                Assert.IsNotNull(thousand);
                Assert.AreEqual("One thousand", thousand.Name);

                var item = new NumberName
                {
                    Name = "Five Thousand"
                };
                session.Add(item);

                var byKey = session.GetByIdentifier<NumberName, int>(5005);

                Assert.AreSame(item, byKey);
            }
        }
    }
}
